package com.dap.dubbo.rpc.config;

import org.redisson.Redisson;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

public class RedisConfig implements InitializingBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisConfig.class);

    //最大连接数
    private String redis_max_active="100";

   //最大空闲连接数
    private String redis_max_idle="10";

   //获取连接时最大等待毫秒数,如果该值小于0,则阻塞不确定的时长,默认值-1
    private String redis_max_wait="1500";

    //超时
    private String redis_timeout="2000";

    /**
     * sentinels 哨兵地址信息
     */
    private String redis_addr;

    /**
     * 是否哨兵
     */
    private String redis_sentinel="true";

    /**
     * 集群名称
     */
    private String redis_clustername;

    /**
     * 单机连接池
     */
    private static JedisPool jedisPool = null;
    /**
     * 哨兵连接池
     */
    private static JedisSentinelPool redisSentinelJedisPool = null;

    /**
     * Redissionconfig配置
     */
    private static Config redissionconfig = new Config();

    /**
     * Redissionconfig操作对象
     */
    private static RedissonClient redissonClient = null;

    @Override
    public void afterPropertiesSet()  {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(Integer.parseInt(redis_max_active));
            config.setMaxIdle(Integer.parseInt(redis_max_idle));
            config.setMaxWaitMillis(Integer.parseInt(redis_max_wait));
            // 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的
            config.setTestOnBorrow(true);
            // 哨兵模式
            if ("true".equalsIgnoreCase(redis_sentinel)) {
                Set<String> sentinels = getRedisSentinels(redis_addr);
                redisSentinelJedisPool = new JedisSentinelPool(
                        redis_clustername, sentinels, config);
                //
                redissionconfig.useSentinelServers().addSentinelAddress("redis://"+redis_addr).setMasterName(redis_clustername);
                redissonClient = Redisson.create(redissionconfig);
            } else {
                String address = redis_addr.split(":")[0];
                String port = redis_addr.split(":")[1];
                jedisPool = new JedisPool(config, address,
                        Integer.parseInt(port),
                        Integer.parseInt(redis_timeout));
                redissionconfig.useSingleServer().setAddress("redis://"+redis_addr);
                redissonClient = Redisson.create(redissionconfig);
            }
        } catch (Exception e) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(e.getMessage());
            }
            e.printStackTrace();
        }
    }


    private Set<String> getRedisSentinels(String redis_addr2) {
        Set<String> sentinelSet = new HashSet<String>();
        for (String sentinel : redis_addr2.split("\\|")) {
            sentinelSet.add(sentinel);
        }
        return sentinelSet;
    }




    /**
     * 获取操作对象
     * @return
     */
    public  static Jedis getJedis(){
        Jedis resource = null;
        if (jedisPool != null) {
            try {
                resource = jedisPool.getResource();
            } catch (Throwable t) {
                if (resource != null) {
                    resource.close();
                    resource = null;
                }
            }
        } else if (redisSentinelJedisPool != null) {
            try {
                resource = redisSentinelJedisPool.getResource();
            } catch (Throwable t) {
                if (resource != null) {
                    resource.close();
                    resource = null;
                }
            }
        }
        return resource;
    }

    /**
     * 使用RedissonClient得到锁
     * @param lockName 锁名
     */
    public static RLock getLock(String lockName){
         RLock mylock = redissonClient.getLock(lockName);
         return mylock;
    }


    public String getRedis_max_active() {
        return redis_max_active;
    }

    public void setRedis_max_active(String redis_max_active) {
        this.redis_max_active = redis_max_active;
    }

    public String getRedis_max_idle() {
        return redis_max_idle;
    }

    public void setRedis_max_idle(String redis_max_idle) {
        this.redis_max_idle = redis_max_idle;
    }

    public String getRedis_max_wait() {
        return redis_max_wait;
    }

    public void setRedis_max_wait(String redis_max_wait) {
        this.redis_max_wait = redis_max_wait;
    }

    public String getRedis_timeout() {
        return redis_timeout;
    }

    public void setRedis_timeout(String redis_timeout) {
        this.redis_timeout = redis_timeout;
    }

    public String getRedis_addr() {
        return redis_addr;
    }

    public void setRedis_addr(String redis_addr) {
        this.redis_addr = redis_addr;
    }

    public String getRedis_sentinel() {
        return redis_sentinel;
    }

    public void setRedis_sentinel(String redis_sentinel) {
        this.redis_sentinel = redis_sentinel;
    }

    public String getRedis_clustername() {
        return redis_clustername;
    }

    public void setRedis_clustername(String redis_clustername) {
        this.redis_clustername = redis_clustername;
    }
}
